package com.gonsin.gnews;

import com.gonsin.gnews.annotations.model.GNewsPageRequest;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NewsUtils {

    /**
     * 扫描批注
     */
    @SneakyThrows
    public static void scannerPackage(String[] packages, TypeFilter[] typeFilters, Consumer<Class<?>> consumer) {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        for (TypeFilter filter : typeFilters) {
            scanner.addIncludeFilter(filter);
        }
        for (String pack : packages) {
            for (BeanDefinition bd : scanner.findCandidateComponents(pack)) {
                consumer.accept(Class.forName(bd.getBeanClassName()));
            }
        }
    }

    /**
     * 转换类型
     */
    public static Pageable toPageable(GNewsPageRequest pageRequest){
        if(pageRequest == null){
            return PageRequest.of(0, Integer.MAX_VALUE);
        }
        Sort sort = null;
        if(StringUtils.isNotEmpty(pageRequest.getSort())){
            List<String> sortItems = Arrays.asList(pageRequest.getSort().split(","));
            for(int i = 0; i < sortItems.size(); i++){
                String item = sortItems.get(i);
                if(!item.startsWith("+") && !item.startsWith("-")){
                    continue;
                }
                String sortBy = item.substring(1);
                Sort.Direction sortDirection = pageRequest.getSort().startsWith("+") ? Sort.Direction.ASC : Sort.Direction.DESC;
                if(sort == null){
                    sort = Sort.by(sortDirection, humpToLine(sortBy));
                } else {
                    sort = sort.and(Sort.by(sortDirection, humpToLine(sortBy)));
                }
            }
        }

        if(sort == null){
            sort = Sort.unsorted();
        }
        Pageable pageable = PageRequest.of(pageRequest.getPage(), pageRequest.getCount(), sort);
        return pageable;
    }


    private static Pattern humpPattern = Pattern.compile("[A-Z]");
    private static String humpToLine(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString().toUpperCase();
    }

}
